package com.xqq.utils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

public class RadarDataParser {

    // 主解析方法
    public static TrackData parseTrackData(byte[] rawData) {
        ByteBuffer buffer = ByteBuffer.wrap(rawData).order(ByteOrder.BIG_ENDIAN);

        // 1. 验证帧头 (4字节)
        long header = buffer.getInt() & 0xFFFFFFFFL;
        if (header != 0x55AA55AAL) {
            throw new IllegalArgumentException("无效帧头: " + Long.toHexString(header));
        }

        // 2. 帧长度 (4字节)
        int frameLength = buffer.getInt();

        // 3. 指令 (4字节)
        int command = buffer.getInt();
        if (command != 0x00030002) {
            throw new IllegalArgumentException("非航迹指令: " + Integer.toHexString(command));
        }

        // 4. 帧ID (4字节)
        int frameId = buffer.getInt();

        // 5. 公共头部解析 (42字节)
        TrackHeader headerData = parseTrackHeader(buffer);

        // 6. 目标数据解析 (56字节/目标)
        List<TrackTarget> targets = new ArrayList<>();
        for (int i = 0; i < headerData.getTargetCount(); i++) {
            targets.add(parseTrackTarget(buffer));
        }

        // 7. CRC校验 (2字节)
        short crc = buffer.getShort();

        return new TrackData(frameLength, frameId, headerData, targets, crc);
    }

    // 解析公共头部
    private static TrackHeader parseTrackHeader(ByteBuffer buffer) {
        TrackHeader header = new TrackHeader();

        // UTC时间戳 (8字节)
        header.setUtcTimestamp(buffer.getLong());

        // 雷达帧号 (8字节)
        header.setRadarFrameId(buffer.getLong());

        // 上传时间戳 (8字节)
        header.setUploadTimestamp(buffer.getLong());

        // 扫描起始角度 (4字节)
        header.setStartAngle(buffer.getInt() * 0.0001); // 转角度值

        // 扫描结束角度 (4字节)
        header.setEndAngle(buffer.getInt() * 0.0001); // 转角度值

        // 预留字段 (2字节)
        buffer.get(new byte[2]);

        // 北向标志 (1字节)
        header.setNorthReference(buffer.get());

        // 扫描方向 (1字节)
        header.setScanDirection(buffer.get());

        // 目标数量 (4字节)
        header.setTargetCount(buffer.getInt());

        return header;
    }

    // 解析目标数据
    private static TrackTarget parseTrackTarget(ByteBuffer buffer) {
        TrackTarget target = new TrackTarget();

        // 坐标 (12字节)
        target.setX(buffer.getInt() * 0.01); // 转米
        target.setY(buffer.getInt() * 0.01); // 转米
        target.setZ(buffer.getInt() * 0.01); // 转米

        // 速度 (12字节)
        target.setVx(buffer.getInt() * 0.01); // 转m/s
        target.setVy(buffer.getInt() * 0.01); // 转m/s
        target.setVz(buffer.getInt() * 0.01); // 转m/s

        // 目标ID (4字节)
        target.setTargetId(buffer.getInt() & 0xFFFFFFFFL);

        // 信噪比 (2字节)
        target.setSnr(buffer.getShort() * 0.01); // 转dB

        // RCS (2字节)
        target.setRcs(buffer.getShort() * 0.01); // 转m²

        // 预留字段 (6字节)
        buffer.get(new byte[6]);

        // 目标类型 (1字节)
        target.setTargetType(buffer.get());

        // 预留字段 (1字节)
        buffer.get();

        // 预留字段 (16字节)
        buffer.get(new byte[16]);

        // RCS(新) (4字节)
        target.setRcsNew(buffer.getInt());

        // 选中标志 (4字节)
        target.setSelected(buffer.getInt() == 1);

        return target;
    }

    // 辅助方法：十六进制字符串转字节数组
    public static byte[] hexStringToByteArray(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("无效的十六进制字符串");
        }

        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }

    // 辅助方法：格式化时间戳
    public static String formatTimestamp(long timestamp, boolean isMicroseconds) {
        long millis = isMicroseconds ? timestamp / 1000 : timestamp;
        Date date = new Date(millis);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        return sdf.format(date);
    }

    // 目标类型描述
    public static String getTargetTypeDescription(byte type) {
        switch (type) {
            case 0x00: return "识别未完成";
            case 0x01: return "人";
            case 0x02: return "车";
            case 0x03: return "无人机";
            case 0x04: return "飞鸟";
            case 0x05: return "未识别出目标类型";
            default: return String.format("未知类型 (0x%02X)", type);
        }
    }

    // 数据结构定义
    public static class TrackData {
        private int frameLength;
        private int frameId;
        private TrackHeader header;
        private List<TrackTarget> targets;
        private short crc;

        public TrackData(int frameLength, int frameId, TrackHeader header, List<TrackTarget> targets, short crc) {
            this.frameLength = frameLength;
            this.frameId = frameId;
            this.header = header;
            this.targets = targets;
            this.crc = crc;
        }

        // Getters
        public int getFrameLength() { return frameLength; }
        public int getFrameId() { return frameId; }
        public TrackHeader getHeader() { return header; }
        public List<TrackTarget> getTargets() { return targets; }
        public short getCrc() { return crc; }
    }

    public static class TrackHeader {
        private long utcTimestamp;      // 雷达启动时间 (微秒)
        private long radarFrameId;      // 雷达内部帧号
        private long uploadTimestamp;   // 当前帧时间 (毫秒)
        private double startAngle;      // 扫描起始角度 (度)
        private double endAngle;        // 扫描结束角度 (度)
        private byte northReference;    // 北向标志 (0=正北, 1=转台零位)
        private byte scanDirection;     // 扫描方向 (0=顺时针, 2=逆时针)
        private int targetCount;        // 目标数量

        // Setters
        public void setUtcTimestamp(long utcTimestamp) { this.utcTimestamp = utcTimestamp; }
        public void setRadarFrameId(long radarFrameId) { this.radarFrameId = radarFrameId; }
        public void setUploadTimestamp(long uploadTimestamp) { this.uploadTimestamp = uploadTimestamp; }
        public void setStartAngle(double startAngle) { this.startAngle = startAngle; }
        public void setEndAngle(double endAngle) { this.endAngle = endAngle; }
        public void setNorthReference(byte northReference) { this.northReference = northReference; }
        public void setScanDirection(byte scanDirection) { this.scanDirection = scanDirection; }
        public void setTargetCount(int targetCount) { this.targetCount = targetCount; }

        // Getters
        public long getUtcTimestamp() { return utcTimestamp; }
        public long getRadarFrameId() { return radarFrameId; }
        public long getUploadTimestamp() { return uploadTimestamp; }
        public double getStartAngle() { return startAngle; }
        public double getEndAngle() { return endAngle; }
        public byte getNorthReference() { return northReference; }
        public byte getScanDirection() { return scanDirection; }
        public int getTargetCount() { return targetCount; }
    }

    public static class TrackTarget {
        private double x;            // X坐标 (m)
        private double y;            // Y坐标 (m)
        private double z;            // Z坐标 (m)
        private double vx;           // X速度 (m/s)
        private double vy;           // Y速度 (m/s)
        private double vz;           // Z速度 (m/s)
        private long targetId;      // 目标ID
        private double snr;          // 信噪比 (dB)
        private double rcs;          // RCS (m²)
        private byte targetType;     // 目标类型
        private int rcsNew;          // RCS(新) (1e-6m²)
        private boolean selected;   // 选中标志

        // Setters
        public void setX(double x) { this.x = x; }
        public void setY(double y) { this.y = y; }
        public void setZ(double z) { this.z = z; }
        public void setVx(double vx) { this.vx = vx; }
        public void setVy(double vy) { this.vy = vy; }
        public void setVz(double vz) { this.vz = vz; }
        public void setTargetId(long targetId) { this.targetId = targetId; }
        public void setSnr(double snr) { this.snr = snr; }
        public void setRcs(double rcs) { this.rcs = rcs; }
        public void setTargetType(byte targetType) { this.targetType = targetType; }
        public void setRcsNew(int rcsNew) { this.rcsNew = rcsNew; }
        public void setSelected(boolean selected) { this.selected = selected; }

        // Getters
        public double getX() { return x; }
        public double getY() { return y; }
        public double getZ() { return z; }
        public double getVx() { return vx; }
        public double getVy() { return vy; }
        public double getVz() { return vz; }
        public long getTargetId() { return targetId; }
        public double getSnr() { return snr; }
        public double getRcs() { return rcs; }
        public byte getTargetType() { return targetType; }
        public int getRcsNew() { return rcsNew; }
        public boolean isSelected() { return selected; }

        // 计算附加信息
        public double getHorizontalRange() {
            return Math.sqrt(x * x + y * y);
        }

        public double getAzimuth() {
            return Math.toDegrees(Math.atan2(x, y));
        }

        public double getPitch() {
            double range = Math.sqrt(x * x + y * y + z * z);
            return Math.toDegrees(Math.asin(z / range));
        }

        public double getSpeed() {
            return Math.sqrt(vx * vx + vy * vy + vz * vz);
        }
    }

    // 测试方法
    public static void main(String[] args) {
        // 示例报文数据
        String hexData = "55AA55AA000000720003000200000001000626C1E848F1FB00000000000000C5" +
                "00000193234DE994002710000029810000000000000001FFF93E1A0002108F00" +
                "003BDCFFFFFCE20000018900000023000E72C012E90001000000000000000000" +
                "0000000000000000000000000000000000000000000000000000000000000000" +
                "CCCC";

        // 转换十六进制字符串为字节数组
        byte[] rawData = hexStringToByteArray(hexData);

        try {
            // 解析航迹数据
            TrackData trackData = parseTrackData(rawData);

            // 打印解析结果
            printTrackData(trackData);
        } catch (Exception e) {
            System.err.println("解析错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 打印解析结果
    private static void printTrackData(TrackData trackData) {
        TrackHeader header = trackData.getHeader();

        System.out.println("==== 雷达航迹数据帧解析结果 ====");
        System.out.println("帧长度: " + trackData.getFrameLength() + " 字节");
        System.out.println("帧ID: " + trackData.getFrameId());
        System.out.println("CRC校验: 0x" + Integer.toHexString(trackData.getCrc() & 0xFFFF).toUpperCase());

        System.out.println("\n==== 公共头部信息 ====");
        System.out.println("UTC时间戳: " + formatTimestamp(header.getUtcTimestamp(), true) +
                " (0x" + Long.toHexString(header.getUtcTimestamp()) + ")");
        System.out.println("雷达帧号: " + header.getRadarFrameId() +
                " (0x" + Long.toHexString(header.getRadarFrameId()) + ")");
        System.out.println("上传时间戳: " + formatTimestamp(header.getUploadTimestamp(), false) +
                " (0x" + Long.toHexString(header.getUploadTimestamp()) + ")");
        System.out.printf("扫描角度: %.4f° - %.4f°%n", header.getStartAngle(), header.getEndAngle());
        System.out.println("北向基准: " + (header.getNorthReference() == 0 ? "正北" : "转台零位"));
        System.out.println("扫描方向: " + (header.getScanDirection() == 0 ? "顺时针" : "逆时针"));
        System.out.println("目标数量: " + header.getTargetCount());

        System.out.println("\n==== 目标详细信息 ====");
        for (int i = 0; i < trackData.getTargets().size(); i++) {
            TrackTarget target = trackData.getTargets().get(i);
            System.out.println("--- 目标 #" + (i + 1) + " ---");
            System.out.printf("位置: X=%.2fm, Y=%.2fm, Z=%.2fm%n", target.getX(), target.getY(), target.getZ());
            System.out.printf("速度: Vx=%.2fm/s, Vy=%.2fm/s, Vz=%.2fm/s%n",
                    target.getVx(), target.getVy(), target.getVz());
            System.out.println("目标ID: " + target.getTargetId() +
                    " (0x" + Long.toHexString(target.getTargetId()) + ")");
            System.out.printf("信噪比: %.2f dB%n", target.getSnr());
            System.out.printf("RCS: %.4f m²%n", target.getRcs());
            System.out.printf("RCS(新): %.6f m²%n", target.getRcsNew() * 1e-6);
            System.out.println("目标类型: " + getTargetTypeDescription(target.getTargetType()));
            System.out.println("选中状态: " + (target.isSelected() ? "已选中" : "未选中"));

            System.out.printf("水平距离: %.2fm, 方位角: %.2f°, 俯仰角: %.2f°%n",
                    target.getHorizontalRange(), target.getAzimuth(), target.getPitch());
            System.out.printf("速度大小: %.2f m/s%n", target.getSpeed());
        }
    }
}
